#include <QApplication>
#include <QFileSystemModel>
#include <QTreeView>
#include <QListView>
#include <QTableView>
#include <QStandardItemModel>
#include <QPixmap>
#include <QListView>
#include <QTableView>
#include <QList>
#include <QDebug>


/*
模型/视图框架：
    管理数据，展示数据

    MVC设计模式：
        （Model-View-Controller）是一种常用的设计模式，用于将应用程序的数据、用户界面和业务逻辑分离开来，以提高代码的可维护性和可扩展性。


    M:model：
        模型代表应用程序的数据和业务逻辑。它负责处理数据的读取、存储、更新和验证，并提供与数据相关的接口供其他组件使用。
        在Qt中，模型通常是继承自QAbstractItemModel的类，用于提供数据的访问和修改接口。

        用来表示数据， 本身并不一定要存储数据，也可以用来春存储数据
        QStringListModel:  QStringList      存储很多QString
        QStandardItemModel: 处理复杂的树形结构的数据
        QFileSystemModel:   处理本地磁盘文件/目录数据

        QAbstractItemModel: 他的子类（上面那些）都会根基数据结构的这个层次关系来表示数据，视图就会按照这种约定的方式，按照模型里面指定的数据模式，把数据显示出来
        当模型中的数据发生改变的时候，模型就会通过信号槽的机制来通知关联的视图
            简单说就是   当模型数据改变时，视图也跟着改变；
                例如，文件系统模式设置监视当前系统目录，如果我给目录里添加一个新的文件，视图也会跟着添加并显示刚添加的文件

        常见的三种模型：1.列表模型      2.表格模型      3.树形模型
            项角色






    V: View     ：
        视图负责显示模型的数据，并与用户进行交互。它通常是用户界面的一部分，可以是一个窗口、一个部件或一个图形项。视图从模型中读取数据，并将其显示给用户。
        在Qt中，视图通常是继承自QWidget或QGraphicsItem的类，用于显示数据和响应用户输入。

        用户界面        表格（table）   列表（list）    树（tree）
        QListView,QTabView

        视图可以适用多种视图方式写出来一个模型





    C:  controller：
        控制器是模型和视图之间的中介，负责处理用户输入、更新模型的数据，并将更新的数据传递给视图进行显示。
        它接收用户的操作，解释这些操作，并根据需要调用模型的方法来更新数据。在Qt中，控制器通常是继承自QObject的类，用于处理用户输入和管理模型和视图之间的通信。

        用户输入的一些反应




    MVC设计模式的优点包括：
            分离关注点：将应用程序的数据、用户界面和业务逻辑分离开来，使代码结构更清晰，易于理解和维护。
            可扩展性：通过将模型、视图和控制器解耦，可以更容易地对应用程序进行扩展和修改，而不会影响其他部分的代码。
            可重用性：通过将模型和视图分离，可以在不同的界面上重用相同的模型，或者在不同的模型上使用相同的视图。
    在Qt中，MVC设计模式广泛应用于诸如Qt Widgets和Qt Quick等框架中，以实现数据驱动的用户界面开发。
    例如，Qt Widgets中的QTableView和QTreeView是基于MVC设计模式的，它们使用模型来提供数据，并使用视图来显示和编辑数据。
    同样，Qt Quick中的Qt Quick Controls和Qt Quick Models模块也使用了MVC设计模式来实现数据驱动的用户界面开发。


*/


int main(int argc,char* argv[])
{
    QApplication a(argc,argv);


    //文件系统模型：
#if 0
    //定义个文件系统模型：
    QFileSystemModel model;
    //设置当前监视的目录：
    model.setRootPath(QDir::currentPath());

    //创建树形视图：
    QTreeView treeview;
    //为视图指定模型
    treeview.setModel(&model);

    //设置根索引：
    treeview.setRootIndex(model.index(QDir::currentPath()));
    treeview.show();


    //创建列表视图：
    QListView listview;
    listview.setModel(&model);
    listview.setRootIndex(model.index(QDir::currentPath()));
    listview.show();

    //treeview 和listview    两个都能显示出来，显示的是两个窗口
#endif




        //树形模型：
#if 1
    //创建标准项模型：
    QStandardItemModel model;
    //获取模型的根项，根项不可见：
    QStandardItem* item = model.invisibleRootItem();

    //创建多个标准项 item：
    QStandardItem* item0 = new QStandardItem;
    item0->setText("河南");
    QPixmap pix0(20,20);
    pix0.fill(Qt::yellow);
    item0->setIcon(pix0);
    item0->setToolTip("河南");

    item->appendRow(item0);

    QStandardItem* item1 = new QStandardItem;
    item1->setText("郑州");
    QPixmap pix1(20,20);
    pix1.fill(Qt::red);
    item1->setIcon(pix1);
    item1->setToolTip("郑州");

    item0->appendRow(item1);

    QStandardItem* item2 = new QStandardItem;
//    item2->setText("洛阳");
//    QPixmap pix2(20,20);
//    pix2.fill(Qt::green);
//    item2->setIcon(pix2);
//    item2->setToolTip("洛阳");
    QPixmap pix2(20,20);
    pix2.fill(Qt::green);
    item2->setData("洛阳",Qt::EditRole);                              //他以适合在编辑器中编辑的形式提供数据。
    item2->setData("洛阳",Qt::ToolTipRole);                        //项目的工具提示中显示的数据
    item2->setData(QIcon(pix2),Qt::DecorationRole);         //要以图标形式呈现为修饰的数据

    item0->appendRow(item2);

    QStandardItem* item3 = new QStandardItem;
    item3->setText("东北");
    QPixmap pix3(20,20);
    pix3.fill(Qt::blue);
    item3->setIcon(pix3);
    item3->setToolTip("东北");

    item->appendRow(item3);

    //视图：       1.树视图
    QTreeView treeview;
    treeview.setModel(&model);
    treeview.show();

    QModelIndex index1 = model.index(0,0,QModelIndex());
    qDebug()<<"row count:>"<<model.rowCount(index1);

    QModelIndex index2 = model.index(0,0,index1);
    qDebug()<<"index2 text:>"<<model.data(index2,Qt::EditRole).toString();
    qDebug()<<"index2 ToolTip:>"<<model.data(index2,Qt::ToolTipRole).toString();

#endif


    //列表模型：
#if 0

    QList<QStandardItem*> listItem;

    QStandardItemModel model;
    //获取模型的根项，根项不可见：
    QStandardItem* item = model.invisibleRootItem();

    //创建多个标准项 item：
    QStandardItem* item0 = new QStandardItem;
    item0->setText("河南");
    QPixmap pix0(20,20);
    pix0.fill(Qt::yellow);
    item0->setIcon(pix0);
    item0->setToolTip("河南");

    QStandardItem* item1 = new QStandardItem;
    item1->setText("郑州");
    QPixmap pix1(20,20);
    pix1.fill(Qt::red);
    item1->setIcon(pix1);
    item1->setToolTip("郑州");

    QStandardItem* item2 = new QStandardItem;
    item2->setText("洛阳");
    QPixmap pix2(20,20);
    pix2.fill(Qt::green);
    item2->setIcon(pix2);
    item2->setToolTip("洛阳");

    QStandardItem* item3 = new QStandardItem;
    item3->setText("东北");
    QPixmap pix3(20,20);
    pix3.fill(Qt::blue);
    item3->setIcon(pix3);
    item3->setToolTip("东北");

    listItem <<item0<<item1<<item2<<item3;
    item->appendColumn(listItem);       //列
    //item->appendRow(listItem);       //行

    //视图：       1.表格视图
    QListView listview;
    listview.setModel(&model);
    listview.show();
#endif

    return a.exec();
}
